package com.fan.flowable.web;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.flowable.variable.api.history.HistoricVariableInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class HelloController {

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    ProcessEngine processEngine;

    @Autowired
    HistoryService historyService;

    /**
     * 部署可以有很多方式
     */
    @GetMapping("/deploy")
    public void deploy() {
//        这种适合导出然后导入的情况
        String filePath = "";
        try {
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
                    .addClasspathResource(filePath);
            Deployment deployment = deploymentBuilder.deploy();
//            logger.info("成功：部署工作流成：" + filePath);
//            return deployment;
        } catch (Exception e) {
//            logger.error("失败：部署工作流：" + e);
//            return null;
        }

//下面这种适合从前端直接传xml过来
//        Deployment deployment = null;
//        try {
//            deployment = repositoryService.createDeployment()
//                    .name(processDTO.getProcessName())
//                    .key(processPublishDTO.getProcessKey())
//                    .tenantId(processPublishDTO.getTenantId())
//                    .addBytes(processPublishDTO.getProcessKey() + ".bpmn20.xml", processPublishDTO.getProcessXml().getBytes("UTF-8"))
//                    .deploy();

        }


    @GetMapping("/plist")
    public void searchProcess() {
//        流程定义（xml中的相关节点）
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
//        流程实例（启动的）
        List<ProcessInstance> list1 = runtimeService.createProcessInstanceQuery().list();
        System.out.println(list);
        System.out.println(list1);

    }


    /**
     * 根据流程id返回流程图，用红框显示处理阶段
     *
     * @param resp
     * @param processId
     * @throws Exception
     */
    @GetMapping("/pic")
    public void showPic(HttpServletResponse resp, String processId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
        if (pi == null) {
            return;
        }
        List<Execution> executions = runtimeService
                .createExecutionQuery()
                .processInstanceId(processId)
                .list();

        List<String> activityIds = new ArrayList<>();
        List<String> flows = new ArrayList<>();
        for (Execution exe : executions) {
            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
            activityIds.addAll(ids);
        }

        /**
         * 生成流程图
         */
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, false);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int legth = 0;
        try {
            out = resp.getOutputStream();
            while ((legth = in.read(buf)) != -1) {
                out.write(buf, 0, legth);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    /**
     * 开启一个流程（非process下的需要部署才能启动）
     */
    @GetMapping("/start")
    public void startProcess() {
        String staffId = "1000";
        HashMap<String, Object> map = new HashMap<>();
        map.put("leaveTask", staffId);
        map.put("name","测试人");
        map.put("reason","休息一下");

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ask_for_leave", map);
//        runtimeService.setVariable(processInstance.getId(), "name", "javaboy");
//        runtimeService.setVariable(processInstance.getId(), "reason", "休息一下");
//        runtimeService.setVariable(processInstance.getId(), "days", 10);
        System.out.println("创建请假流程 processId：{" + processInstance.getId());

    }

    /**
     * 员工将任务退给组长审批
     */
    @GetMapping("/commitZ")
    public void commitZ() {
        String zuzhangId = "90";
        String staffId = "1000";
        //员工查找到自己的任务，然后提交给组长审批
        List<org.flowable.task.api.Task> list = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskId().desc().list();
        for (Task task : list) {
            System.out.println("任务 ID：" + task.getId());
            System.out.println("任务处理人：" + task.getAssignee());
            System.out.println("任务是否挂起：" + task.isSuspended());
            System.out.println("任务节点名称"+task.getName());
            Map<String, Object> map = new HashMap<>();
            //提交给组长的时候，需要指定组长的 id
            map.put("zuzhangTask", zuzhangId);
            taskService.complete(task.getId(), map);
        }
    }

    /**
     * @Method
     * @Author HTHLKJ
     * @Date 2023/4/6
     * @Version 1.0
     * @Description 组长同意
     */
    @GetMapping("/zuapprove")
    public void zuApprove() {
        String zuzhangId = "90";
        String managerId = "55";
        List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();
        for (Task task : list) {
            System.out.println("组长:" + task.getAssignee());
            System.out.println("在审批" + task.getId());
            Map<String, Object> map = new HashMap<>();
            //组长审批的时候，如果是同意，需要指定经理的 id
            map.put("managerTask", managerId);
            map.put("checkResult", "通过");
            taskService.complete(task.getId(), map);

        }
    }

    @GetMapping("/zureject")
    public void zuReject() {
        String zuzhangId = "90";

        List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();
        for (Task task : list) {
            System.out.println("组长:" + task.getAssignee());
            System.out.println("在审批" + task.getId());
            Map<String, Object> map = new HashMap<>();
            //组长审批的时候，如果是拒绝，就不需要指定经理的 id
            map.put("checkResult", "拒绝");
            taskService.complete(task.getId(), map);

        }
    }

    /**
     * 经理审批自己的任务-批准
     */
    @GetMapping("/mapprove")
    void managerApprove() {
        String managerId = "55";
        List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();
        for (Task task : list) {
            System.out.println("经理:" + task.getAssignee());
            System.out.println("在审批" + task.getId());
            Map<String, Object> map = new HashMap<>();
            map.put("checkResult", "通过");
            taskService.complete(task.getId(), map);
        }
    }

    @GetMapping("/mreject")
    void managerReject() {
        String managerId = "55";
        List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();
        for (Task task : list) {
            System.out.println("经理:" + task.getAssignee());
            System.out.println("在审批" + task.getId());
            Map<String, Object> map = new HashMap<>();
            map.put("checkResult", "拒绝");
            taskService.complete(task.getId(), map);
        }
    }

    /**
     * 执行完成后数据会在run表中删除，只能在history表中查到
     * @param processId
     */
    @GetMapping("/history")
    public void  selectHistory(String processId){
//        历史参数
        List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().executionId(processId).list();
//        历史人物流程
        List<HistoricActivityInstance> list1 = historyService.createHistoricActivityInstanceQuery().executionId(processId).list();
        System.out.println("hello");
    }


}

